#include "line.h"
#include "utilities.h"

GeometryUtilities::Line::Line()
: mYIntercept(0.0), mXIntercept(0.0), mSlope(0.0),
  mIsVertical(false), mIsHorizontal(false) {}

GeometryUtilities::Line::Line(const GeometryUtilities::Point &p1,
                              const GeometryUtilities::Point &p2)
{
  mIsVertical = Utilities::floatEquality(p1.x() - p2.x(), 0.01);
  mIsHorizontal = Utilities::floatEquality(p1.y() - p2.y(), 0.01);
  if (mIsVertical) mSlope = 0;
  else mSlope = (p2.y() - p1.y())/(p2.x() - p1.x());
  if (!mIsHorizontal)
  {
    mYIntercept = p1.y() - mSlope*p1.x();
  }
  else
  {
     mYIntercept = p1.y();
  }

  if (!mIsVertical)
  {
    mXIntercept = -mYIntercept/mSlope;
  }
  else
  {
    mXIntercept = p1.x();
  }
}

GeometryUtilities::Line::Line(qreal yIntercept, qreal slope)
: mYIntercept(yIntercept), mSlope(slope) {}

bool GeometryUtilities::Line::isHorizontal() const {return mIsHorizontal;}
bool GeometryUtilities::Line::isVertical() const {return mIsVertical;}
qreal GeometryUtilities::Line::slope() const {return mSlope;}
qreal GeometryUtilities::Line::yIntercept() const {return mYIntercept;}
qreal GeometryUtilities::Line::xIntercept() const {return mXIntercept;}



bool GeometryUtilities::Line::isPointOn(const GeometryUtilities::Point &p) const
{
  return Utilities::floatEquality(mSlope*p.x()+mYIntercept, p.y());
}

bool GeometryUtilities::Line::operator==(const GeometryUtilities::Line& rhs) const
{
  return Utilities::floatEquality(mSlope,rhs.slope()) &&
         Utilities::floatEquality(mYIntercept, rhs.yIntercept());
}
